#include "Character.h"
//#include "Pen.h"
#include "Object Files.h"

Character::Character() : BaseObject()
{
	Init();
}

Character::Character(Character const & C) : BaseObject()
{
	m_vPosition = C.m_vPosition;
	m_fHealth = C.m_fHealth;
	m_fGold = C.m_fGold;
	m_BoundingBox = C.m_BoundingBox;
	m_Mesh = C.m_Mesh;
	m_pTexture = C.m_pTexture;
	m_Type = C.m_Type;
	m_fScale = C.m_fScale;
	CameraMan.EyePos = C.CameraMan.EyePos;
	CameraMan.LookAt = C.CameraMan.LookAt;
	m_LightRange = C.m_LightRange;
}

Character::Character(Character const & C, D3DXVECTOR3 P) : BaseObject()
{
	m_vPosition = P;
	m_fHealth = C.m_fHealth;
	m_fGold = C.m_fGold;
	m_BoundingBox = C.m_BoundingBox;
	m_Mesh = C.m_Mesh;
	m_pTexture = C.m_pTexture;
	m_Type = C.m_Type;
	m_fScale = C.m_fScale;
	CameraMan.EyePos = C.CameraMan.EyePos;
	CameraMan.LookAt = C.CameraMan.LookAt;
	m_LightRange = C.m_LightRange;
}

Character::Character(D3DXVECTOR3 Pos) : BaseObject()
{
	m_vPosition = Pos;
	Init();
}

Character::Character(float x,float y,float z) : BaseObject()
{
	m_vPosition = D3DXVECTOR3(x,y,z);
	Init();
}

Character::Character(float x,float y,float z,float GOLD) : BaseObject()
{
	m_vPosition = D3DXVECTOR3(x,y,z);
	Init();
	m_fGold = GOLD;
}

void Character::Init()
{
	m_fHealth = 100;
	m_fGold = 0;
#ifdef IMPLEMENT_SWORD
	m_dirAttackDir = NullDirection;
	m_MyWeapon = new Sword;
	m_MyWeapon->SetPosition(D3DXVECTOR3(m_vPosition.x,m_vPosition.y,m_vPosition.z-.01f));
#endif
	m_BoundingBox.top		= (LONG)(m_vPosition.y + 2.5);
	m_BoundingBox.left		= (LONG)(m_vPosition.x + 2.5);
	m_BoundingBox.bottom	= (LONG)(m_vPosition.y - 2.5);
	m_BoundingBox.right		= (LONG)(m_vPosition.x - 2.5);
	m_Mesh = Pen::Engine()->getMeshByIndex(CHARACTER_MESH);
	m_pTexture = Pen::Engine()->getTextureByIndex(PLAYER_TEXTURE);
	m_Type = PLAYER_TYPE;
	m_fScale = 1.0f;
	CameraMan.EyePos = GetCameraPosition();
	CameraMan.LookAt = GetPosition();
	m_LightRange = 70;
}

//Used to talk to the Menu mostly but able to tell anyone if needed
void Character::SendStats(int To)
{
	Messenger::Engine()->SendMessageA(STATS_HEALTH,m_fHealth,To);
	Messenger::Engine()->SendMessageA(STATS_EXP,m_fGold,To);
}

void Character::TranslateMessages()
{
	Messenger::Engine()->ReceiveMessages(this);
	if(m_Messages.getSize() != 0)
	{
		for(int i = 0;i < m_Messages.getSize();++i)
		{
			switch(m_Messages.get(i)->MessageType)
			{
			case DAMAGE:
				m_fHealth -= *m_Messages.get(i)->Info;
				Messenger::Engine()->ClearMessage(m_Messages.get(i));
				break;
			/*case HEAL:
				m_fHealth += *pMsg->Info;
				Messenger::Engine()->ClearMessage(pMsg);
				break;*/
			case GIVE:
				m_fGold += *m_Messages.get(i)->Info;
				Messenger::Engine()->ClearMessage(m_Messages.get(i));
				break;
			default:
				break;
			}
		}
		m_Messages.Clear();
	}
}

bool Character::Collided(DrawList* drawables,D3DXVECTOR3 NewPos)
{
	int TotalDis = 0;
	D3DXVECTOR3 ChangeinPos = NewPos - m_vPosition;
	//If it isnt able to clip it skips this whole function
	if(CLIP)
	{
		for(int i = 0;i < drawables->getSize();++i)
		{
			if(m_iID != drawables->get(i)->m_iID)
			{
				//Distance between the two objects
				// if its close enough it goes into the harder computations
				/*TotalDis = (int)(drawables->get(i)->m_vPosition.x - NewPos.x + drawables->get(i)->m_vPosition.y - NewPos.y);

				if(TotalDis <= 50
					&& */
				if((ChangeinPos.x + this->m_BoundingBox.right < drawables->get(i)->m_BoundingBox.left)
					&& (ChangeinPos.x + this->m_BoundingBox.left > drawables->get(i)->m_BoundingBox.right)
					&& (ChangeinPos.y + this->m_BoundingBox.bottom < drawables->get(i)->m_BoundingBox.top)
					&& (ChangeinPos.y + this->m_BoundingBox.top > drawables->get(i)->m_BoundingBox.bottom))
				{
					switch(drawables->get(i)->m_Type)
					{
					case ITEM_TYPE:
						switch(((Pickup*)(drawables->get(i)))->m_PUType)
						{
						case GOLD_TYPE:
						case END_MARKER_TYPE:
							Messenger::Engine()->SendMessageA(FOUND,0,drawables->get(i)->m_iID);
							break;
						}
						break;
					case ENEMY_TYPE:
						Messenger::Engine()->SendMessageA(DAMAGE,1,drawables->get(i)->m_iID);
					default:
						return CLIP;
					}
				}
			}
		}
	}
	return false;
}

//Move bounding box to current position
void Character::UpdateBox()
{
	m_BoundingBox.top		= (LONG)(m_vPosition.y + 3);
	m_BoundingBox.left		= (LONG)(m_vPosition.x + 3);
	m_BoundingBox.bottom	= (LONG)(m_vPosition.y - 3);
	m_BoundingBox.right		= (LONG)(m_vPosition.x - 3);
}

void Character::Draw()
{
	m_Mesh->DrawSubset(m_dwSubset);
}

//Removed due to time constraints
#ifdef IMPLEMENT_SWORD
D3DXVECTOR3 Character::WeaponPos(eDirections Dir)
{
	D3DXVECTOR3 P = m_vPosition;
	switch(Dir)
	{
	case NORTH:
		P.y += 3;
		break;
	case SOUTH:
		P.y -= 3;
		break;
	case EAST:
		P.x -= 3;
		break;
	case WEST:
		P.x += 3;
		break;
	default: break;
	}
	P.z -= .01f;
	return P;
}
#endif

void* Character::Update(void* Info)
{
	UpdateBox();
#ifdef IMPLEMENT_SWORD
	m_MyWeapon->SetPosition(WeaponPos(m_dirAttackDir));
#endif
	TranslateMessages();
	return NULL;
}